import torch

class adict(dict):
    ''' Attribute dictionary - a convenience data structure, similar to SimpleNamespace in python 3.3
        One can use attributes to read/write dictionary content.
    '''
    def __init__(self, *av, **kav):
        dict.__init__(self, *av, **kav)
        self.__dict__ = self


def encode_sent_pair(tt, pair):
    return tt.encode(pair[0], text_pair=pair[1], add_special_tokens=True)

def encode_sent_pairs(tt, sent_pairs):
    return [encode_sent_pair(tt, pair) for pair in sent_pairs]

def pad_sentences(sent_list, padding_value, max_sent_len=256):
    max_len = min( max(map(lambda s:len(s), sent_list)), max_sent_len)
    batchsize = len(sent_list)
    out = torch.empty([batchsize, max_len], dtype=torch.int64).fill_(padding_value)
    mask = torch.ones([batchsize, max_len])
    for i, sent in enumerate(sent_list):
        sent_len = min(len(sent), max_len)
        out[i, :sent_len] = torch.tensor(sent[:sent_len])
        mask[i, sent_len:].fill_(0.0)
    return out, mask

def encode_sent_list(tt, sent_list):
    return [tt.encode(sent.strip("\t"), add_special_tokens=True) for sent in sent_list]


def Entrophy(pred):
    assert pred.ndim == 2
    prob = pred.softmax(dim=1)
    return -1*(prob*torch.log(prob)).sum(dim=1).mean()
